//
//  FernkampfWaffe.cs
//
//  Author:
//       Philipp Schröck <philsch@hotmail.de>
//
//  Copyright (c) 2013 Philipp Schröck
//
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU Lesser General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
using System;
using libcharakter.Talente.Kampf;
using System.Collections.Generic;

namespace libcharakter.ausrüstung.Waffen.Fernkampf
{
    public enum FernkampfShotErg
    {
        Good,
        Fail,
        Patzer,
        NoShoot,
        NoArrow
    }
   
    [Serializable]
    public class ReichweitenMod
    {
        public int Reichweiter { get; private set; }
        public int TP { get; private set; }

        public ReichweitenMod() { Reichweiter = 0; TP = 0; }
        public ReichweitenMod(int r, int tp) { Reichweiter = r; TP = tp; }


        public override string ToString()
        {
            return string.Format("{0} ({1})", Reichweiter, TP);
        }
    }
    [Serializable]
    public class FernkampfWaffe : Waffe
    {
        protected ReichweitenMod[] m_reichweiteMod;
        protected int m_aktionen;
        private int m_lastShootAktion;
        protected int[] m_ermod;
       
        private static int m_tpSchaden;

        public FernkampfWaffe(string name, decimal gewicht, int preis, WaffenType type, int tp, ReichweitenMod[] mod,
            int ladeAktionen,bool lWunde, int schuss = 10)
            : base(name, gewicht,preis, type, tp, true, schuss, lWunde)
        {
            m_reichweiteMod = mod;
            m_aktionen = ladeAktionen;
            m_lastShootAktion = 0;

            m_ermod = new int[] { -2, 0, +4, +8, +12 };
        }

        public FernkampfShotErg Shoot(int aktion, int entfernung, Enemy ziel)
        {
            return Shoot(aktion, WuerfelList.GetNumber(20), entfernung, ziel);
        }
        public FernkampfShotErg Shoot(int aktion, int w20, int entfernung, Enemy ziel)
        {
            if (!GetNewShoot())
                return FernkampfShotErg.NoArrow;

            if ((aktion - m_lastShootAktion) > m_aktionen)
                return FernkampfShotErg.NoShoot;

            bool erg = false;
            int mod = 0;
            mod += ziel.ShootModifikation;
            int tp = 0;

            if ((entfernung < m_reichweiteMod [0].Reichweiter) ||
                (entfernung > m_reichweiteMod [4].Reichweiter))
                throw new OdtkFernkampfNotInRanger(this);
            else if (entfernung == m_reichweiteMod [0].Reichweiter)
            {
                mod += m_ermod [0];
                tp += m_reichweiteMod [0].TP;
            } else
            {
                for (int i = 0; i < m_reichweiteMod.Length-1;)
                {

                    if (entfernung.IsInRange(m_reichweiteMod [i].Reichweiter, m_reichweiteMod [i++].Reichweiter))
                    {
                        mod += m_ermod [i];
                        tp += m_reichweiteMod [i].TP;

                        break;
                    }

                }

            }
            m_lastShootAktion = aktion;
            try
            {
                erg = ((w20) <= m_at - mod);
                m_tpSchaden = (m_plusTP + tp);

            } catch (OdtkPatzer)
            {
                return FernkampfShotErg.Patzer;
            }

            return erg ? FernkampfShotErg.Good :
                FernkampfShotErg.Fail; 
        }
        public override int Schaden(int w6, Enemy ziel)
        {
            return (w6 + m_tpSchaden) - ziel.RuestungsSchutz;
        }
        public override bool Equip(Charakter chr)
        {
            m_usingTalent = (KampfTalent)chr.FindTalent("Bogen");

            if (m_usingTalent != null)
            {
                m_at = m_usingTalent.Attacke;
                m_pa = m_usingTalent.Parade;
                return true;
            }
            return false;
        }

        public override string ToString()
        {
            string format = string.Format("{0} RW: {1}/{2}/{3}/{4}/{5} TP+:{6}/{7}/{8}/{9}/{10}  FK: {12} TP: 1W6+{11} Geschosse: {13}",
                                          Name, m_reichweiteMod[0].Reichweiter,
                                          m_reichweiteMod[1].Reichweiter, m_reichweiteMod[2].Reichweiter, m_reichweiteMod[3].Reichweiter,
                                          m_reichweiteMod[4].Reichweiter, m_reichweiteMod[0].TP, m_reichweiteMod[1].TP,
                                          m_reichweiteMod[2].TP, m_reichweiteMod[3].TP, m_reichweiteMod[4].TP, m_plusTP, m_at, m_stapel);



            return format;
        }
        protected virtual bool GetNewShoot()
        {
            if (m_stapel - 1 < 0)
                return false;
            else
            {
                m_stapel -= 1;
                return true;
            }
        }
    }
}

